package com.cskaoyan.market.admin.controller;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import com.cskaoyan.market.admin.bo.GoodsCombineBo;
import com.cskaoyan.market.admin.service.AdminGoodsService;
import com.cskaoyan.market.admin.service.MarketGoodsService;
import com.cskaoyan.market.admin.service.impl.AdminGoodsServiceImpl;
import com.cskaoyan.market.admin.service.impl.MarketGoodsServiceImpl;
import com.cskaoyan.market.admin.vo.DetailGoodsVo;
import com.cskaoyan.market.admin.vo.UpdateGoodsBo;
import com.cskaoyan.market.db.domain.MarketGoods;
import com.cskaoyan.market.db.domain.MarketGoodsAttribute;
import com.cskaoyan.market.db.domain.MarketGoodsProduct;
import com.cskaoyan.market.db.domain.MarketGoodsSpecification;
import com.cskaoyan.market.util.AdminResponseCode;
import com.cskaoyan.market.util.HttpUtil;
import com.cskaoyan.market.util.JacksonUtil;
import com.cskaoyan.market.util.ResponseUtil;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @author James
 * @since 2023/03/20 19:44
 */
@WebServlet("/admin/goods/*")
public class AdminGoodsController extends HttpServlet {
    private MarketGoodsService goodsService = new MarketGoodsServiceImpl();
    private AdminGoodsService adminGoodsService = new AdminGoodsServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 先来进行doGet的方法分发
        String replace = req.getRequestURI().replace(req.getContextPath() + "/admin/goods/", "");
        if ("list".equals(replace)) {
            list(req, resp);
        } else if ("catAndBrand".equals(replace)) {
            catAndBrand(req, resp);
        } else if ("detail".equals(replace)) {
            detail(req, resp);
        }

    }

    private void detail(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String id = req.getParameter("id");
        if (StringUtils.isEmpty(id)) {
            resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.badArgument()));
            return;
        }
        DetailGoodsVo detailGoodsVo = goodsService.detail(id);
        resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.ok(detailGoodsVo)));

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 方法分发
        String replace = req.getRequestURI().replace(req.getContextPath() + "/admin/goods/", "");
        if ("create".equals(replace)) {
            createGoods(req, resp);
        }
        if ("update".equals(replace)) {
            update(req, resp);
        }
        if ("delete".equals(replace)) {
            delete(req, resp);
        }

    }

    private void createGoods(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取位于请求题里面的字符串
        String requestBody = HttpUtil.getRequestBody(req);
        ObjectMapper objectMapper = JacksonUtil.getObjectMapper();
        // 此处我们传递的对象无论是goods还是products还是specifications都无法接收该数据，是一个组合体，可以新建一个对象来接收该数据
        GoodsCombineBo combineBo = null;
        try {
            combineBo = objectMapper.readValue(requestBody, GoodsCombineBo.class);
        } catch (Exception e) {
            resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.fail(402, "参数值不对")));
            return;
        }

        // 校验
        MarketGoods goods = combineBo.getGoods();
        MarketGoodsSpecification[] specifications = combineBo.getSpecifications();
        MarketGoodsProduct[] products = combineBo.getProducts();
        MarketGoodsAttribute[] attributes = combineBo.getAttributes();
        int code = valid(attributes, goods, products, specifications);
        if (code == 404) {
            // 如果校验的结果是404，那么数据不符合要求，不可以保存
            resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.badArgument()));
            return;
        }
        int result = adminGoodsService.addGoods(goods, specifications, products, attributes);
        if (result == 500) {
            resp.getWriter().println(
                    JacksonUtil.writeValueAsString(ResponseUtil.fail(AdminResponseCode.GOODS_NAME_EXIST, "插入商品时失败")));
            return;
        }
        resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.ok()));
    }

    private int valid(MarketGoodsAttribute[] attributes, MarketGoods goods, MarketGoodsProduct[] products,
                      MarketGoodsSpecification[] specifications) {
        for (MarketGoodsAttribute attribute : attributes) {
            if (StringUtils.isEmpty(attribute.getAttribute()) || StringUtils.isEmpty(attribute.getValue())) {
                return 404;
            }
        }
        for (MarketGoodsSpecification specification : specifications) {
            if (StringUtils.isEmpty(specification.getSpecification())
                    || StringUtils.isEmpty(specification.getValue())) {
                return 404;
            }
        }

        if (StringUtils.isEmpty(goods.getName())) {
            return 404;
        }

        return 200;
    }

    private void delete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String requestBody = HttpUtil.getRequestBody(req);
        String id = JacksonUtil.parseString(requestBody, "id");
        if (StringUtils.isEmpty(id)) {
            resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.badArgument()));
            return;
        }
        goodsService.delete(id);
        resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.ok()));

    }

    /**
     * 返回当前商城的商品分类和品牌商 "categoryList": [{ "value": 1005001, "label": "餐厨", "children": [{ "value": 1005007, "label":
     * "锅具" }]}] "brandList": [{ "value": 1001000, "label": "MUJI制造商" }]
     *
     * @param req
     * @param resp
     */
    private void catAndBrand(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        Map<String, Object> result = goodsService.catAndBrand();
        resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.ok(result)));
    }

    /**
     * 该接口用来去显示商品的信息，需要去接收请求参数 1.获取请求参数？如何获取，是json解析吗？不是，因为提交的不是json字符串类型的参数，而是key=value request.getParameter即可
     *
     * @param req
     * @param resp
     */
    private void list(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        // 获取参数
        String pageParameter = req.getParameter("page");
        String limitParameter = req.getParameter("limit");
        String goodsSn = req.getParameter("goodsSn");

        String name = req.getParameter("name");
        String sort = req.getParameter("sort");
        String order = req.getParameter("order");
        String goodsIdParam = req.getParameter("goodsId");

        // 校验 ,page和limit这两个参数是必须要有的 ,sort和order如果没有要指定默认
        if (StringUtils.isEmpty(pageParameter) || StringUtils.isEmpty(limitParameter)) {
            resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.badArgument()));
            return;
        }
        if (StringUtils.isEmpty(sort)) {
            sort = "add_time";
        }
        if (StringUtils.isEmpty(order)) {

            order = "desc";
        }

        // 如果商品编号不为空,那也必须是一个整数
        int page = 0;
        int limit = 0;
        try {
            limit = Integer.parseInt(limitParameter);
            page = Integer.parseInt(pageParameter);

        } catch (NumberFormatException e) {
            resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.badArgument()));
            return;
        }
        // 调用goodsService获取实体对象并且返回
        List<MarketGoods> list = goodsService.list(page, limit, goodsSn, name, sort, order, goodsIdParam);
        resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.okList(list)));
    }

    private void update(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String requestBody = HttpUtil.getRequestBody(req);
        ObjectMapper objectMapper = JacksonUtil.getObjectMapper();
        UpdateGoodsBo updateGoodsBo = objectMapper.readValue(requestBody, UpdateGoodsBo.class);
        MarketGoodsAttribute[] attributes = updateGoodsBo.getAttributes();
        MarketGoods goods = updateGoodsBo.getGoods();
        MarketGoodsProduct[] products = updateGoodsBo.getProducts();
        MarketGoodsSpecification[] specifications = updateGoodsBo.getSpecifications();
        int code = valid(attributes, goods, products, specifications);

        if (code == 404) {
            resp.getWriter().println(JacksonUtil.writeValueAsString(ResponseUtil.badArgument()));
            return;
        }
        if (code == 200) {
            goodsService.update(attributes, goods, products, specifications);

        }
    }
}